﻿using Microsoft.Extensions.Options;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;

namespace StackExchange.Redis.Core.Extensions
{
    public partial class RedisCache
    {
        #region SQLSugar缓存实现
        /// <summary>
        /// 创建一个默认的RedisCache
        /// </summary>
        public static RedisCache CreateDefault()
        {
            return new RedisCache(Options.Create(new RedisCacheOptions()));
        }

        public bool ContainsKey(string key)
        {
            var cache = Connect();
            return cache.KeyExists(_options.InstanceName + key);
        }

        public bool ContainsKey<V>(string key)
        {
            return ContainsKey(key);
        }

        public void Add<V>(string key, V value)
        {
            Add(key, value, int.MaxValue);
        }

        public void Add<V>(string key, V value, int cacheDurationInSeconds)
        {
            if (cacheDurationInSeconds <= 0) { cacheDurationInSeconds = 20 * 60; }
            this.SetString(key, JsonConvert.SerializeObject(value),
                new DistributedCacheEntryOptions()
                .SetAbsoluteExpiration(TimeSpan.FromSeconds(cacheDurationInSeconds))
                .SetSlidingExpiration(TimeSpan.FromSeconds(cacheDurationInSeconds)));
        }

        public V Get<V>(string key)
        {
            return JsonConvert.DeserializeObject<V>(this.GetString(key));
        }

        public void Remove<V>(string key)
        {
            this.Remove(key);
        }

        public IEnumerable<string> GetAllKey<V>()
        {
            return GetAllKey();
        }

        public V GetOrCreate<V>(string cacheKey, Func<V> create, int cacheDurationInSeconds = int.MaxValue)
        {
            if (cacheDurationInSeconds <= 0) { cacheDurationInSeconds = 20 * 60; }
            if (ContainsKey(cacheKey))
            {
                return Get<V>(cacheKey);
            }
            else
            {
                var result = create();
                Add<V>(cacheKey, result, cacheDurationInSeconds);
                return result;
            }
        }

        public IEnumerable<string> GetAllKey()
        {
            var cache = Connect();
            var points = cache.Multiplexer.GetEndPoints();
            foreach (var item in points)
            {
                var p = cache.Multiplexer.GetServer(item);
                var keys = p.Keys(cache.Database, _options.InstanceName + "*");
                var en = keys.GetEnumerator();
                while (en.MoveNext())
                {
                    yield return en.Current;
                }
            }
        }
        #endregion
    }
}
